#ifndef PROCESS_EXECUTOR_HPP
#define PROCESS_EXECUTOR_HPP
#include <string>
#include <vector>
#include <memory>
#include <iostream>
#include <sstream>
#include <errno.h>
#include <chrono>
#include <boost/process.hpp>
#include <boost/asio.hpp>
#include <system_error> 
#include "log_manager.hpp"
class ProcessExecutor
{
    enum processstatus
    {
        PROCESS_STATUS_RUNNING = 0,
        PROCESS_STATUS_STOPPED = 1,
        PROCESS_STATUS_ERROR = 2,
        PROCESS_STATUS_UNKNOWN = 3,
    };
public:
    ProcessExecutor(std::string name, std::string bin, std::vector<std::string> args = {}):name_(name), bin_(bin), args_(args),status_(PROCESS_STATUS_UNKNOWN) {
        std::cout << "ProcessExecutor constructor" << std::endl;
        LogManager::getInstance("log.txt").log(LogManager::LogLevel::INFO, "ProcessExecutor constructor");
    }
    ~ProcessExecutor(){
        std::cout << "ProcessExecutor destructor" << std::endl;
        stop();
    }
    void start() {
        if (isRunning()) {
            std::cout << "Process is already running." << std::endl;
            return;
        }
        try {
            // 尝试启动进程
            process_ = boost::process::child(bin_, args_);

            // 检查进程是否成功启动
            if (!process_.running()) {
                std::cerr << "Failed to start process." << std::endl;
                LogManager::getInstance("log.txt").log(LogManager::LogLevel::ERROR, "Failed to start process.");
                status_ = PROCESS_STATUS_ERROR;
                throw std::system_error(errno, std::system_category(), "Failed to start process.");
            } else {
                std::cout << "Process started successfully." << std::endl;
                status_ = PROCESS_STATUS_RUNNING;
            }
        } catch (const boost::process::process_error& e) {
            std::cerr << "Error starting process: " << e.what() << std::endl;
            LogManager::getInstance("log.txt").log(LogManager::LogLevel::ERROR, "Error starting process: " + std::string(e.what()));
            status_ = PROCESS_STATUS_ERROR;
            throw std::system_error(errno, std::system_category(), "Failed to start process.");
        }
    }

    void stop() {
        if (isRunning()) {
            try{
                process_.terminate(); // 尝试正常终止进程

                boost::asio::io_context io_context;
                boost::asio::steady_timer timer(io_context, std::chrono::seconds(5));

                timer.async_wait([&](const boost::system::error_code& /*ec*/) {
                    if (this->isRunning()) {
                        ::kill(process_.id(), SIGKILL);
                        process_.wait(); // 等待进程结束，确保资源被释放
                    }
                });

                io_context.run(); // 启动 ASIO 处理，等待超时或进程结束

                // 如果进程已经正常结束，或在上述检查后判定已结束
                if (!this->isRunning()) {
                    status_ = PROCESS_STATUS_STOPPED;
                    // 获取并处理退出状态
                    std::cout << this->getName() << "Process stopped." << "exit code: " << process_.exit_code() << std::endl;
                } else {
                    std::cerr << "Failed to stop process." << std::endl;
                    LogManager::getInstance("log.txt").log(LogManager::LogLevel::ERROR, "Failed to stop process.");
                }
            } //boost::process::process_error std::exception
            catch (const boost::process::process_error& e ) {
                std::cerr << "Error stopping process: " << e.what() << std::endl;
                status_ = PROCESS_STATUS_ERROR;
                throw std::system_error(errno, std::system_category(), "Failed to stop process.");
                LogManager::getInstance("log.txt").log(LogManager::LogLevel::ERROR, "Error stopping process: " + std::string(e.what()));
            }
            catch (const std::exception& e) {
                std::cerr << "Error stopping process: " << e.what() << std::endl;
                status_ = PROCESS_STATUS_ERROR;
                throw std::system_error(errno, std::system_category(), "Failed to stop process.");
                LogManager::getInstance("log.txt").log(LogManager::LogLevel::ERROR, "Error stopping process: " + std::string(e.what()));
            }
        }
    }
    void restart() {
        stop();
        start();
    }
    bool isRunning() const {
        return process_.valid() && process_.running();
    }
    pid_t getPid() const {
        return process_.id();
    }
    std::string getName() const {
        return name_;
    }
    std::string getBin() const {
        return bin_;
    }
private:
    mutable boost::process::child process_;
    std::string name_;
    std::string bin_;
    std::vector<std::string> args_;
    int status_;
};

#endif //PROCESS_EXECUTOR_HPP